// -------------------- iSharePoint -------------------- //
// 
//  Company:	IT Complex, LLC
//  Project:	Smart.Common
//  File name:	ValueWithSupplement.cs
//  Developer:	Igor Solomatov
//  Created:	05.03.2013
// 
// -------------------- iSharePoint -------------------- //

using System;

namespace Smart
{
	[Serializable]
	public class ValueWithSupplement<TValueType, TSupplementType> : IEquatable<TValueType>, IEquatable<ValueWithSupplement<TValueType, TSupplementType>>
	{
		public readonly TValueType Value;
		public TSupplementType Supplement;

		public ValueWithSupplement()
		{
		}

		public ValueWithSupplement(TValueType value)
		{
			Value = value;
		}

		public ValueWithSupplement(TValueType value, TSupplementType supplement)
		{
			Value = value;
			Supplement = supplement;
		}

		public static implicit operator TValueType(ValueWithSupplement<TValueType, TSupplementType> value)
		{
			return value.Value;
		}

		public static implicit operator ValueWithSupplement<TValueType, TSupplementType>(TValueType value)
		{
			return new ValueWithSupplement<TValueType, TSupplementType>(value);
		}

		[NonSerialized]
		private int? _hashCode;

		public override int GetHashCode()
		{
			// ReSharper disable NonReadonlyFieldInGetHashCode
			return _hashCode ?? (_hashCode = Value.GetHashCode()).Value;
			// ReSharper restore NonReadonlyFieldInGetHashCode
		}

		public override bool Equals(object other)
		{
			var another = other as ValueWithSupplement<TValueType, TSupplementType>;

			return Value.Equals(another != null ? another.Value : other);
		}

		public bool Equals(TValueType other)
		{
			return Value.Equals(other);
		}

		public bool Equals(ValueWithSupplement<TValueType, TSupplementType> other)
		{
			return Value.Equals(other.Value);
		}
	}
}